package com.example.choupaiapp;

import android.app.Application;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.StrictMode;
import android.support.annotation.Nullable;
import android.support.multidex.MultiDex;

import com.dueeeke.videoplayer.ijk.IjkPlayerFactory;
import com.dueeeke.videoplayer.player.VideoViewConfig;
import com.dueeeke.videoplayer.player.VideoViewManager;
import com.example.choupaiapp.common.constant.Contacts;
import com.example.choupaiapp.common.util.ContextUtil;
import com.example.choupaiapp.common.util.SharedPreferencesHelp;
import com.example.choupaiapp.main.constant.Config;
import com.example.choupaiapp.main.view.GlideNineImageLoader;
import com.example.choupaiapp.main.view.MyGlideNineImageLoader;
import com.example.choupaiapp.main.view.MyNineGridView;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMOptions;
import com.hyphenate.easeui.EaseUI;
import com.hyphenate.push.EMPushHelper;
import com.hyphenate.push.EMPushType;
import com.hyphenate.push.PushListener;
import com.hyphenate.util.EMLog;
import com.lzy.ninegrid.NineGridView;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheMode;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.Logger;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreator;
import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreator;
import com.scwang.smartrefresh.layout.api.RefreshFooter;
import com.scwang.smartrefresh.layout.api.RefreshHeader;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.footer.ClassicsFooter;
import com.scwang.smartrefresh.layout.header.ClassicsHeader;
import com.tencent.bugly.crashreport.CrashReport;
import com.tencent.smtt.sdk.QbSdk;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
import com.zzhoujay.richtext.RichText;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;

import cn.jpush.android.api.JPushInterface;


/**
 * Created by ASUS on 2019/10/25.
 */

public class App extends Application {
    //static 代码段可以防止内存泄露
    static {
        //设置全局的Header构建器
        SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() {
            @Override
            public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
                layout.setPrimaryColorsId(R.color.white, R.color.common_color);//全局设置主题颜色
                //指定为经典Header，默认是 贝塞尔雷达Header
                //.setTimeFormat(new DynamicTimeFormat("更新于 %s"))
                return new ClassicsHeader(context);
            }
        });
        //设置全局的Footer构建器
        SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() {
            @Override
            public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {
                //指定为经典Footer，默认是 BallPulseFooter
//                layout.setPrimaryColorsId(R.color.white, R.color.common_color);
                return new ClassicsFooter(context).setDrawableSize(20);
            }
        });
    }

    @Override
    public void onCreate() {
        super.onCreate();

        //初始化全局上下文
        ContextUtil.init(this);

        //内存泄漏
//        if (!LeakCanary.isInAnalyzerProcess(this)) {
//            LeakCanary.install(this);
//        }

        //初始化腾讯X5
        initX5();

        //初始化bugly
        initBugly();

        //关闭9.0弹窗
        closeAndroidPDialog();

        //初始化友盟
        initUmeng();

        //初始化登录信息
        SharedPreferencesHelp.initSharedPreferences(this, "CHOU_PAI", Context.MODE_PRIVATE);

        //Logger 上线改为Release
        Logger.addLogAdapter(new AndroidLogAdapter() {
            @Override
            public boolean isLoggable(int priority, @Nullable String tag) {
                return Contacts.DEBUG;
            }
        });

        // 设置开启日志,发布时请关闭日志
        JPushInterface.setDebugMode(Contacts.DEBUG);
        // 初始化 JPush
        JPushInterface.init(this);

        //初始化网络请求
        initHttp();

        //初始化相册选择
        initGallerFinal();

        //初始化环信
        initIM();

        //初始化富文本
        RichText.initCacheDir(App.this);

        //初始化九宫格
        NineGridView.setImageLoader(new GlideNineImageLoader());
        MyNineGridView.setImageLoader(new MyGlideNineImageLoader());
    }

    private void initUmeng() {
//        UMConfigure.init(this, Config.UMENG_APP_KEY, "Android", UMConfigure.DEVICE_TYPE_PHONE, null);
        UMConfigure.init(this, UMConfigure.DEVICE_TYPE_PHONE, null);
        UMConfigure.setLogEnabled(Contacts.DEBUG);
        MobclickAgent.setSessionContinueMillis(1000 * 40);
        // 选用MANUAL页面采集模式
        MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.MANUAL);
        // 支持在子进程中统计自定义事件
        UMConfigure.setProcessEvent(true);
    }

    private void initX5() {
//        QbSdk.setDownloadWithoutWifi(true);
        //搜集本地tbs内核信息并上报服务器，服务器返回结果决定使用哪个内核。
        QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {

            @Override
            public void onViewInitFinished(boolean arg0) {
                // TODO Auto-generated method stub
                //x5內核初始化完成的回调，为true表示x5内核加载成功，否则表示x5内核加载失败，会自动切换到系统内核。
                Logger.e("qbsdk" + arg0);
            }

            @Override
            public void onCoreInitFinished() {
                // TODO Auto-generated method stub
            }
        };
        //x5内核初始化接口
        QbSdk.initX5Environment(this, cb);
    }

    private void initBugly() {
        CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(this);
        strategy.setAppReportDelay(10000);
        strategy.setCrashHandleCallback(new CrashReport.CrashHandleCallback() {

            public Map<String, String> onCrashHandleStart(int crashType, String errorType, String errorMessage, String errorStack) {

                LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();

                String x5CrashInfo = com.tencent.smtt.sdk.WebView.getCrashExtraMessage(App.this);

                map.put("x5crashInfo", x5CrashInfo);

                return map;

            }

            @Override
            public byte[] onCrashHandleStart2GetExtraDatas(int crashType, String errorType, String errorMessage, String errorStack) {

                try {

                    return "Extra data.".getBytes("UTF-8");

                } catch (Exception e) {

                    return null;

                }

            }

        });
        CrashReport.initCrashReport(getApplicationContext(), Config.BUGLY_APP_ID, Contacts.DEBUG, strategy);
    }


    private void initIM() {
        EMOptions options = new EMOptions();
        // 默认添加好友时，是不需要验证的，改成需要验证
//        options.setAcceptInvitationAlways(false);
        // 是否自动将消息附件上传到环信服务器，默认为True是使用环信服务器上传下载，如果设为 false，需要开发者自己处理附件消息的上传和下载
        options.setAutoTransferMessageAttachments(true);
        // 是否自动下载附件类消息的缩略图等，默认为 true 这里和上边这个参数相关联
        options.setAutoDownloadThumbnail(true);
        if (EaseUI.getInstance().init(this, options)) {
            //在做打包混淆时，关闭debug模式，避免消耗不必要的资源
            EMClient.getInstance().setDebugMode(Contacts.DEBUG);

        }

        // 请确保环信SDK相关方法运行在主进程，子进程不会初始化环信SDK（该逻辑在EaseUI.java中）
        if (EaseUI.getInstance().isMainProcess(this)) {
            // 初始化华为 HMS 推送服务, 需要在SDK初始化后执行
//            HMSPushHelper.getInstance().initHMSAgent(instance);

            EMPushHelper.getInstance().setPushListener(new PushListener() {
                @Override
                public void onError(EMPushType pushType, long errorCode) {
                    // TODO: 返回的errorCode仅9xx为环信内部错误，可从EMError中查询，其他错误请根据pushType去相应第三方推送网站查询。
                    EMLog.e("PushClient", "Push client occur a error: " + pushType + " - " + errorCode);
                }
            });

        }
    }


    private void initGallerFinal() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy(builder.build());
            builder.detectFileUriExposure();
        }

        //播放器配置，注意：此为全局配置，按需开启
        VideoViewManager.setConfig(VideoViewConfig.newBuilder()
                .setLogEnabled(Contacts.DEBUG)
                .setPlayerFactory(IjkPlayerFactory.create())
                .setPlayOnMobileNetwork(false)
//                .setPlayerFactory(ExoMediaPlayerFactory.create())
//                .setEnableOrientation(true)
                .setEnableMediaCodec(false)
//                .setUsingSurfaceView(true)
//                .setEnableParallelPlay(true)
//                .setEnableAudioFocus(true)
//                .setScreenScaleType(VideoView.SCREEN_SCALE_MATCH_PARENT)
                .build());


//        RxGalleryFinalApi.setImgSaveRxSDCard("choupai_image");
//        RxGalleryFinalApi.setImgSaveRxCropSDCard("choupai_image/crop");//裁剪会自动生成路径；也可以手动设置裁剪的路径；

//        //设置主题
//        //ThemeConfig.CYAN
//        ThemeConfig theme = new ThemeConfig.Builder()
//                .setTitleBarBgColor(Color.parseColor("#ff60a7ff"))
//                .build();
//        //配置功能
//        FunctionConfig functionConfig = new FunctionConfig.Builder()
//                .setEnableCamera(true)
////                .setEnableEdit(true)
////                .setEnableCrop(true)
//                .setEnableRotate(true)
////                .setCropSquare(true)
//                .setEnablePreview(true)
//                .build();
//
//        //配置imageloader
//        ImageLoader imageloader = new GlideImageLoader();
//        CoreConfig coreConfig = new CoreConfig.Builder(this, imageloader, theme)
////                .setDebug(BuildConfig.DEBUG)
//                .setFunctionConfig(functionConfig)
//                .build();
//        GalleryFinal.init(coreConfig);
    }

    /**
     * 网络框架
     */
    private void initHttp() {
        OkGo.getInstance().init(this).setCacheMode(CacheMode.REQUEST_FAILED_READ_CACHE);
//        OkHttpClient.Builder builder = new OkHttpClient.Builder();
//        //全局的读取超时时间
//        builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
//        //全局的写入超时时间
//        builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
//        //全局的连接超时时间
//        builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);

//        //使用sp保持cookie，如果cookie不过期，则一直有效
//        builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));
//        //使用数据库保持cookie，如果cookie不过期，则一直有效
//        builder.cookieJar(new CookieJarImpl(new DBCookieStore(this)));
//        //使用内存保持cookie，app退出后，cookie消失
//        builder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));

//        //方法一：信任所有证书,不安全有风险
//        HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
//        //方法二：自定义信任规则，校验服务端证书
//        HttpsUtils.SSLParams sslParams2 = HttpsUtils.getSslSocketFactory(new SafeTrustManager());
//        //方法三：使用预埋证书，校验服务端证书（自签名证书）
//        HttpsUtils.SSLParams sslParams3 = HttpsUtils.getSslSocketFactory(getAssets().open("srca.cer"));
//        //方法四：使用bks证书和密码管理客户端证书（双向认证），使用预埋证书，校验服务端证书（自签名证书）
//        HttpsUtils.SSLParams sslParams4 = HttpsUtils.getSslSocketFactory(getAssets().open("xxx.bks"), "123456", getAssets().open("yyy.cer"));
//        builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);
//        //配置https的域名匹配规则，详细看demo的初始化介绍，不需要就不要加入，使用不当会导致https握手失败
//        builder.hostnameVerifier(new SafeHostnameVerifier());

        //---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//
//        HttpHeaders headers = new HttpHeaders();
//        headers.put("commonHeaderKey1", "commonHeaderValue1");    //header不支持中文，不允许有特殊字符
//        headers.put("commonHeaderKey2", "commonHeaderValue2");
//        HttpParams params = new HttpParams();
//        params.put("commonParamsKey1", "commonParamsValue1");     //param支持中文,直接传,不要自己编码
//        params.put("commonParamsKey2", "这里支持中文参数");
        //-------------------------------------------------------------------------------------//

//        OkGo.getInstance().init(this)                       //必须调用初始化
//                .setOkHttpClient(builder.build())               //建议设置OkHttpClient，不设置将使用默认的
//                .setCacheMode(CacheMode.REQUEST_FAILED_READ_CACHE)               //全局统一缓存模式，默认不使用缓存，可以不传
//                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局统一缓存时间，默认永不过期，可以不传
//                .setRetryCount(0);                            //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0
//                .addCommonHeaders(headers)                      //全局公共头
//                .addCommonParams(params);                       //
    }

    private void closeAndroidPDialog() {
        if (Build.VERSION.SDK_INT >= 28) {
            try {
                Class aClass = Class.forName("android.content.pm.PackageParser$Package");
                Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class);
                declaredConstructor.setAccessible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                Class cls = Class.forName("android.app.ActivityThread");
                Method declaredMethod = cls.getDeclaredMethod("currentActivityThread");
                declaredMethod.setAccessible(true);
                Object activityThread = declaredMethod.invoke(null);
                Field mHiddenApiWarningShown = cls.getDeclaredField("mHiddenApiWarningShown");
                mHiddenApiWarningShown.setAccessible(true);
                mHiddenApiWarningShown.setBoolean(activityThread, true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
        fixTimeoutException();
    }

    private void fixTimeoutException() {
        if (Build.BRAND.equalsIgnoreCase("oppo") && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            try {
                Class clazz = Class.forName("java.lang.Daemons$FinalizerWatchdogDaemon");

                Method method = clazz.getSuperclass().getDeclaredMethod("stop");
                method.setAccessible(true);

                Field field = clazz.getDeclaredField("INSTANCE");
                field.setAccessible(true);

                method.invoke(field.get(null));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    @Override
    public Resources getResources() {//还原字体大小
        Resources res = super.getResources();
        Configuration configuration = res.getConfiguration();
        if (configuration.fontScale != 1.0f) {
            configuration.fontScale = 1.0f;
            res.updateConfiguration(configuration, res.getDisplayMetrics());
        }
        return res;
    }
}
